/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.openbrew.openbrewrf;

import java.io.Serializable;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Date;
import java.util.List;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement;

/**
 *
 * @author chapmand
 */
@Entity
@Table(name = "Sales")
@XmlRootElement
@NamedQueries({
    @NamedQuery(name = "Sales.findAll", query = "SELECT s FROM Sales s"),
    @NamedQuery(name = "Sales.findBySId", query = "SELECT s FROM Sales s WHERE s.sId = :sId"),
    @NamedQuery(name = "Sales.findBySNotes", query = "SELECT s FROM Sales s WHERE s.sNotes = :sNotes"),
    @NamedQuery(name = "Sales.findBySDate", query = "SELECT s FROM Sales s WHERE s.sDate = :sDate"),
    @NamedQuery(name = "Sales.findBySalesFGIQty", query = "SELECT s FROM Sales s WHERE s.salesFGIQty = :salesFGIQty"),
    @NamedQuery(name = "Sales.findByKegID", query = "SELECT s FROM Sales s WHERE s.kegID = :kegID"),
    @NamedQuery(name = "Sales.findByPriceOver", query = "SELECT s FROM Sales s WHERE s.priceOver = :priceOver")})
public class Sales implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "SId")
    private Integer sId;
    @Basic(optional = false)
    @NotNull
    @Size(min = 0, max = 100)
    @Column(name = "SNotes")
    private String sNotes;
    @Basic(optional = false)
    @NotNull
    @Column(name = "SDate")
    @Temporal(TemporalType.TIMESTAMP)
    private Date sDate;
    @Basic(optional = false)
    @NotNull
    @Column(name = "SalesFGIQty")
    private int salesFGIQty;
    @Basic(optional = false)
    @NotNull
    @Column(name = "kegID")
    private int kegID;
    @Basic(optional = false)
    @NotNull
    @Column(name = "priceOver")
    private float priceOver;
    @Basic(optional = false)
    @NotNull
    @Column(name = "servingTankVolume")
    private float servingTankVolume;
    @Basic(optional = false)
    @NotNull
    @Column(name = "unitPrice")
    private float unitPrice;
    @JoinColumn(name = "CustID", referencedColumnName = "CId", nullable=true)
    @ManyToOne(optional = true)
    private Customer custID;
    @JoinColumn(name = "SDisc", referencedColumnName = "DiscID", nullable=true)
    @ManyToOne(optional = true)
    private DiscountCode sDisc;
    @JoinColumn(name = "SalesFGIID", referencedColumnName = "FGIID", nullable=true)
    @ManyToOne(optional = true)
    private FinishedGoodsInventory salesFGIID;
    @OneToMany
    @JoinTable(
        name="JTSalesToLegacySales",
        joinColumns={ @JoinColumn(name="SId", referencedColumnName="SId")},
        inverseJoinColumns={ @JoinColumn(name="lsid", referencedColumnName="lsid", unique=true)}
    )
    private List<LegacySales> legacySalesCollection;

    public Sales() {
    }

    public Sales(Integer sId) {
        this.sId = sId;
    }

    public Sales(Integer sId, String sNotes, Date sDate, int salesFGIQty, int kegID, float priceOver) {
        this.sId = sId;
        this.sNotes = sNotes;
        this.sDate = sDate;
        this.salesFGIQty = salesFGIQty;
        this.kegID = kegID;
        this.priceOver = priceOver;
    }

    public Integer getSId() {
        return sId;
    }

    public void setSId(Integer sId) {
        this.sId = sId;
    }

    public Customer getCustID() {
        return custID;
    }

    public void setCustID(Customer custID) {
        this.custID = custID;
    }

    public String getSNotes() {
        return sNotes;
    }

    public void setSNotes(String sNotes) {
        this.sNotes = sNotes;
    }

    public Date getSDate() {
        return sDate;
    }

    public void setSDate(Date sDate) {
        this.sDate = sDate;
    }

    public DiscountCode getSDisc() {
        return sDisc;
    }

    public void setSDisc(DiscountCode sDisc) {
        if(sDisc.getDiscID()!=null){
            this.sDisc = sDisc;
        }
    }

    public FinishedGoodsInventory getSalesFGIID() {
        return salesFGIID;
    }

    public void setSalesFGIID(FinishedGoodsInventory salesFGIID) {
        if(salesFGIID.getFgiid()!=null){
            this.salesFGIID = salesFGIID;
        }
    }

    public int getSalesFGIQty() {
        return salesFGIQty;
    }

    public void setSalesFGIQty(int salesFGIQty) {
        this.salesFGIQty = salesFGIQty;
    }

    public int getKegID() {
        return kegID;
    }

    public void setKegID(int kegID) {
        this.kegID = kegID;
    }

    public float getPriceOver() {
        return priceOver;
    }

    public void setPriceOver(float priceOver) {
        this.priceOver = priceOver;
    }

    public float getServingTankVolume() {
        return servingTankVolume;
    }

    public void setServingTankVolume(float servingTankVolume) {
        this.servingTankVolume = servingTankVolume;
    }

    public List<LegacySales> getLegacySalesCollection() {
        return legacySalesCollection;
    }

    public void setLegacySalesCollection(List<LegacySales> legacySalesCollection) {
        this.legacySalesCollection = legacySalesCollection;
    }

    public float getUnitPrice() {
        return unitPrice;
    }

    public void setUnitPrice(float unitPrice) {
        this.unitPrice = unitPrice;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (sId != null ? sId.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Sales)) {
            return false;
        }
        Sales other = (Sales) object;
        if ((this.sId == null && other.sId != null) || (this.sId != null && !this.sId.equals(other.sId))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "com.openbrew.openbrewrf.Sales[ sId=" + sId + " ]";
    }

    /***********************************************************************
     * Standard display for pricing and discount text, etc.
     **********************************************************************/
    /***********************************************************************
     * Get Line Price (returns line item price based on settings of line)
     * @return Price
     **********************************************************************/
    public double getLinePrice(){
        double price = (double)this.getUnitPrice();
        if(this.getPriceOver()>0){
            price = (double)this.getPriceOver();
        }
        if(this.getSDisc()!=null){
            price = price - (price * (double)this.getSDisc().getDiscNum());
        } 
        return price;
    }

    /***************************************************************************
     * Get Sales Line's subtotal based on settings.
     * @return 
     **************************************************************************/
    public double getLineSubTot(){
        final double subTot = getLinePrice() * (double)this.getSalesFGIQty();
        return subTot;
    }

    /***************************************************************************
     * Get the appropriate discount description based on settings.
     * @return 
     **************************************************************************/
    public String getDiscountText(){
        if(this.getPriceOver()>0){
            return "Price Override";
        } else if (this.getSDisc()!=null) {
            return this.getSDisc().getDiscName();
        } else {
            return "No Discount";
        }
    }

    /***************************************************************************
     * Get String in CSV format for displaying sales line information.
     * @param admin
     * @return 
     **************************************************************************/
    public String getSalesString(final Administration admin){
        final NumberFormat money = new DecimalFormat("$#0.00");
        String str = "";
        final int numUnits = this.getSalesFGIQty();
        str += this.getSalesFGIID().getFGIDescription();
        if(this.getKegID()!=0){
            str += " - " + String.format(admin.getKegPrefix()+"%08d", this.getKegID());
        }
        str +="," + money.format(getLinePrice());
        str +="," + Integer.toString(numUnits);
        str +="," + money.format(getLineSubTot()) + "\n";
        return str;
    }
    
}
